package org.example.result;

import org.example.exception.AbstractException;

import java.beans.ConstructorProperties;
import java.io.Serializable;
import java.util.Optional;

/**
 * 统一数据响应体
 *
 */
public class ResultInfo<T> implements Serializable {
    private static final long serialVersionUID = 1L;

    /**
     * 状态码
     */
    private String status;
    /**
     * 返回数据对象
     */
    private T data;
    /**
     * 描述内容
     */
    private String message;

    public static <T> ResultInfo<T> success() {
        return new ResultInfo<T>(BaseSuccessCode.SUCCESSFUL_OPERATION.code(), BaseSuccessCode.SUCCESSFUL_OPERATION.message(), null);
    }


    public static <T> ResultInfo<T> success(T data) {
        return new ResultInfo<T>(BaseSuccessCode.SUCCESSFUL_OPERATION.code(), BaseSuccessCode.SUCCESSFUL_OPERATION.message(), data);
    }

    public static <T> ResultInfo<T> success(String message, T data) {
        return new ResultInfo<T>(BaseSuccessCode.SUCCESSFUL_OPERATION.code(), message, data);
    }

    public static <T> ResultInfo<T> success(String code, String message, T data) {
        return new ResultInfo<T>(code, message, data);
    }

    public static <T> ResultInfo<T> error() {
        return new ResultInfo<T>(BaseErrorCode.SERVICE_ERROR.code(), BaseErrorCode.SERVICE_ERROR.message(), null);
    }

    public static <T> ResultInfo<T> error(StateCode stateCode) {
        return new ResultInfo<T>(stateCode.code(), stateCode.message(), null);
    }

    public static <T> ResultInfo<T> error(String message) {
        return new ResultInfo<T>(BaseErrorCode.SERVICE_ERROR.code(), message, null);
    }

    public static <T> ResultInfo<T> error(String code, String message) {
        return new ResultInfo<T>(code, message, null);
    }

    public static <T> ResultInfo<T> error(AbstractException ex) {
        String errorCode = Optional.ofNullable(ex.getErrorCode()).orElse(BaseErrorCode.SERVICE_ERROR.code());
        String errorMessage = Optional.ofNullable(ex.getErrorMessage()).orElse(BaseErrorCode.SERVICE_ERROR.message());
        return new ResultInfo<T>(errorCode, errorMessage, null);
    }

    @ConstructorProperties({"status", "message", "data"})
    public ResultInfo(final String status, final String message, final T data) {
        this.status = status;
        this.message = message;
        this.data = data;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    public String toString() {
        return "ResultInfo{" +
                "status='" + status + '\'' +
                ", data=" + data +
                ", message='" + message + '\'' +
                '}';
    }
}
